package com.inspur.edp.formserver.viewmodel.json.model;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;
import com.inspur.edp.das.commonmodel.entity.GspCommonModel;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import com.inspur.edp.das.commonmodel.json.model.CommonModelDeserializer;
import com.inspur.edp.das.commonmodel.json.object.CmObjectDeserializer;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.collection.ValueHelpConfigCollection;
import com.inspur.edp.formserver.viewmodel.common.MappingType;
import com.inspur.edp.formserver.viewmodel.common.TemplateVoInfo;
import com.inspur.edp.formserver.viewmodel.common.VMAuthConfig;
import com.inspur.edp.formserver.viewmodel.common.ViewModelMapping;
import com.inspur.edp.formserver.viewmodel.dataextendinfo.VoDataExtendInfo;
import com.inspur.edp.formserver.viewmodel.json.ExtendPropertiesDeserializer;
import com.inspur.edp.formserver.viewmodel.json.ViewModelJsonConst;
import com.inspur.edp.formserver.viewmodel.json.mapping.ViewModelMappingDeserializer;
import com.inspur.edp.formserver.viewmodel.json.object.ViewObjectDeserializer;
import com.inspur.edp.formserver.viewmodel.json.operation.VmActionCollectionDeserializer;
import java.io.IOException;
import java.util.HashMap;
import com.inspur.edp.formserver.viewmodel.common.InternalExtendActionUtil;
import lombok.SneakyThrows;

/**
 * The  Josn Deserializer Of View Model Definition
 *
 * @ClassName: BizOperationDeserializer
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class ViewModelDeserializer extends CommonModelDeserializer {

  @Override
  protected void beforeCMModelDeserializer(GspCommonModel model){
     GspViewModel vm = (GspViewModel) model;
     vm.setEnableStdTimeFormat(true);
     vm.setAutoConvertMessage(true);
     vm.setDescription("");
     TemplateVoInfo info = new TemplateVoInfo();
     info.setTemplateVoId("");
     info.setTemplateVoPkgName("");
     info.setTemplateVoServiceUnit("");
     vm.setTemplateVoInfo(info);
     vm.setExtendProperties(new HashMap<>());
     VoDataExtendInfo voDataExtendInfo = new VoDataExtendInfo();
     voDataExtendInfo.initVoDataExendInfo(voDataExtendInfo);
     vm.setDataExtendInfo(voDataExtendInfo);
     vm.setActions(new VMActionCollection());
     vm.setSource("");
     vm.setIsGenFilterConvertor(true);
  }
  @Override
  protected GspCommonModel createCommonModel() {
    return new GspViewModel();
  }

  @Override
  protected CmObjectDeserializer createCmObjectDeserializer() {
    return new ViewObjectDeserializer();
  }

  @SneakyThrows
  @Override
  protected boolean readExtendModelProperty(GspCommonModel model, String propertyName,
      JsonParser jsonParser) {
    GspViewModel vm = (GspViewModel) model;
    boolean hasProperty = true;
    switch (propertyName) {
      case ViewModelJsonConst.EnableStdTimeFormat:
        vm.setEnableStdTimeFormat(SerializerUtils.readPropertyValue_boolean(jsonParser,false));
        break;
      case ViewModelJsonConst.Description:
        vm.setDescription(SerializerUtils.readPropertyValue_String(jsonParser));
        break;
      case ViewModelJsonConst.Mapping:
        readMapping(jsonParser, vm);
        break;
      case ViewModelJsonConst.ExtendType:
        SerializerUtils.readPropertyValue_String(jsonParser);
        break;
      case ViewModelJsonConst.ValueHelpConfigs:
        readValueHelpConfigs(jsonParser, vm);
        break;
      case ViewModelJsonConst.Actions:
        readVMActions(jsonParser, vm);
        break;
      case ViewModelJsonConst.ExtendProperties:
        readExtendProperties(jsonParser, vm);
        break;
      case ViewModelJsonConst.DataExtendInfo:
        readDataExtendInfo(jsonParser, vm);
        break;
      case ViewModelJsonConst.TemplateVoInfo:
        readTemplateVoInfo(jsonParser, vm);
        break;
      case ViewModelJsonConst.ConvertMsg:
        vm.setAutoConvertMessage(SerializerUtils.readPropertyValue_boolean(jsonParser));
        break;
      case ViewModelJsonConst.Source:
        vm.setSource(SerializerUtils.readPropertyValue_String(jsonParser));
        break;
      case ViewModelJsonConst.IsGenFilterConvertor:
        vm.setIsGenFilterConvertor(SerializerUtils.readPropertyValue_boolean(jsonParser));
        break;
      case ViewModelJsonConst.Auth:
        readVmAuthConfig(jsonParser, vm);
        break;
      default:
        hasProperty = false;
        break;
    }
    return hasProperty;
  }

  private void readVmAuthConfig(JsonParser jsonParser, GspViewModel vm) throws IOException {
    VMAuthConfig config = SerializerUtils.readPropertyValue_Object(VMAuthConfig.class, jsonParser);
    vm.setAuthConfig(config);
    jsonParser.nextToken();
  }

  private void readTemplateVoInfo(JsonParser jsonParser, GspViewModel vm) {
    JsonDeserializer<TemplateVoInfo> deserializer = new JsonDeserializer<TemplateVoInfo>() {
      @Override
      public TemplateVoInfo deserialize(JsonParser p, DeserializationContext ctxt) {
        TemplateVoInfo info = new TemplateVoInfo();
        SerializerUtils.readStartObject(jsonParser);
        while (jsonParser.getCurrentToken() == JsonToken.FIELD_NAME) {
          String propName = SerializerUtils.readPropertyName(jsonParser);
          switch (propName) {
            case ViewModelJsonConst.TemplateVoId:
              info.setTemplateVoId(SerializerUtils.readPropertyValue_String(jsonParser));
              break;
            case ViewModelJsonConst.TemplateVoPkgName:
              info.setTemplateVoPkgName(SerializerUtils.readPropertyValue_String(jsonParser));
              break;
            case ViewModelJsonConst.TemplateVoServiceUnit:
              info.setTemplateVoServiceUnit(SerializerUtils.readPropertyValue_String(jsonParser));
              break;
            default:
              throw new RuntimeException("未定义TemplateVoInfo" + propName);
          }
        }
        SerializerUtils.readEndObject(jsonParser);
        return info;
      }
    };
    try {
      vm.setTemplateVoInfo(deserializer.deserialize(jsonParser, null));
    } catch (IOException e) {
      throw new RuntimeException("'" + vm.getName() + "'" + "的TemplateVoInfo反序列化失败。");
    }
  }

  private void readValueHelpConfigs(JsonParser jsonParser, GspViewModel vm) {
    SerializerUtils
        .readArray(jsonParser, new ValueHelpConfigDeserizlizer(), vm.getValueHelpConfigs());
  }

  private void readMapping(JsonParser jsonParser, GspViewModel vm) {
    ViewModelMappingDeserializer deserializer = new ViewModelMappingDeserializer();
    vm.setMapping(deserializer.deserialize(jsonParser, null));
  }

  private void readVMActions(JsonParser jsonParser, GspViewModel vm) {
    VmActionCollectionDeserializer deserializer = new VmActionCollectionDeserializer();
    VMActionCollection actions = deserializer.deserialize(jsonParser, null);
//    InternalExtendActionUtil internalExtendActionUtil = new InternalExtendActionUtil();
    for(ViewModelAction action : actions){
//      if(!internalExtendActionUtil.InternalActionIds.contains(action.getID())){
        vm.getActions().add(action);
//      }
    }
  }
  private void initAction(GspViewModel vm){
    vm.setActions(new VMActionCollection());
  }

  private void readExtendProperties(JsonParser jsonParser, GspViewModel vm) {
    ExtendPropertiesDeserializer deserializer = new ExtendPropertiesDeserializer();
    vm.setExtendProperties(deserializer.deserialize(jsonParser, null));
  }

  private void readDataExtendInfo(JsonParser jsonParser, GspViewModel vm) {
    VoDataExtendInfoDeserializer deserializer = new VoDataExtendInfoDeserializer();
    vm.setDataExtendInfo(deserializer.deserialize(jsonParser, null));
  }
}
